#ifndef PLATFORM_H
#define PLATFORM_H

#include <QCoreApplication>
#include <QObject>
#include <QStandardPaths>


/* 鹰：貌似这样不行!!!因为有多次（嵌套）宏定义了
#define CLASS_PLATFORM \
    class _Platform: public QObject \
    { \
        Q_OBJECT \
        Q_ENUMS(QStandardPaths::StandardLocation) \
    public: \
        explicit _Platform(QObject *parent = nullptr): QObject(parent){} \
    public slots: \
        static QString compileType(); \
        static QString applicationDirPath(); \
        static void debug();
*/

#define PLATFORM_GLOBAL_FUNCTION \
        static QString compileType(); \
        static QString applicationDirPath(); \
        static QString separator(); \
        static QString writableLocation(QStandardPaths::StandardLocation); \
        static void debug(); \




#if defined(Q_OS_WIN32)   //win

#define FIXLOCALPATH_R(x) x            //只读本地文件路径
#define FIXLOCALPATH_W(x) x            //读写本地文件路径
//#define FIXLOCALPATH_R(x) (QString("file:") + x)
//#define FIXLOCALPATH_R(x) (QString("qrc:/") + x)
//#define FIXLOCALPATH_W(x) (QString("file:") + x)

#define FIXRESOURCEPATH_R(x) (QString(":/") + x)     //只读资源路径转换
#define FIXRESOURCEURL_R(x) (QString("qrc:/") + x)   //只读资源URL转换


#include <windows.h>


class _Platform: public QObject
{
    Q_OBJECT
    Q_ENUMS(QStandardPaths::StandardLocation)
public:
    explicit _Platform(QObject *parent = nullptr): QObject(parent){}
    virtual ~_Platform(){}
public slots:
    PLATFORM_GLOBAL_FUNCTION


    //一个实例运行
    static bool checkOne(LPCWSTR lpName = L"Pleafles");
};


#elif defined(Q_OS_ANDROID)   //android



#include <QtAndroid>
#include <QAndroidJniEnvironment>
#include <QAndroidJniObject>

using namespace QtAndroid;



#define FIXLOCALPATH_R(x) (QString("assets:/") + x)      //只读本地文件路径
#define FIXLOCALPATH_W(x) x                //读写本地文件路径

#define FIXRESOURCEPATH_R(x) (QString(":/") + x)         //只读资源路径转换
#define FIXRESOURCEURL_R(x) (QString("qrc:/") + x)       //只读资源URL转换


#define WRITE_EXTERNAL_STORAGE "android.permission.WRITE_EXTERNAL_STORAGE"
#define ACCESS_FINE_LOCATION "android.permission.ACCESS_FINE_LOCATION"
#define ACCESS_COARSE_LOCATION "android.permission.ACCESS_COARSE_LOCATION"
#define CAMERA "android.permission.CAMERA"
#define BLUETOOTH_ADMIN "android.permission.BLUETOOTH_ADMIN"
#define BLUETOOTH "android.permission.BLUETOOTH"
#define INSTALL_PACKAGES "android.permission.INSTALL_PACKAGES"
#define RECEIVE_BOOT_COMPLETED "android.permission.RECEIVE_BOOT_COMPLETED"
#define RECORD_AUDIO "android.permission.RECORD_AUDIO"
#define READ_CONTACTS "android.permission.READ_CONTACTS"
#define READ_SMS "android.permission.READ_SMS"
#define RECEIVE_SMS "android.permission.RECEIVE_SMS"
#define RECEIVE_MMS "android.permission.RECEIVE_MMS"
#define RECEIVE_WAP_PUSH "android.permission.RECEIVE_WAP_PUSH"


class _Platform: public QObject
{
    Q_OBJECT
    Q_ENUMS(QStandardPaths::StandardLocation)
public:
    explicit _Platform(QObject *parent = nullptr): QObject(parent){}
    virtual ~_Platform(){}
public slots:
    PLATFORM_GLOBAL_FUNCTION


    //0:横屏(顺时针90度);1:正常;
    /*
    1.landscape：横屏(风景照)显示时宽度大于高度；
    2.portrait：竖屏(肖像照)显示时高度大于宽度；
    3.user：用户当前的首选方向；
    4.behind：继承Activity堆栈中当前Activity下面的那个Activity的方向；
    5.sensor：由物理感应器决定显示方向，它取决于用户如何持有设备，当 设备 被旋转时方向会随之变化——在横屏与竖屏之间；
    6.nosensor：忽略物理感应器——即显示方向与物理感应器无关，不管用户如何旋转设备显示方向都不会随着改变("unspecified"设置除外)；
    7.unspecified：未指定，此为默认值，由Android系统自己选择适当的方向，选择策略视具体设备的配置情况而定，因此不同的设备会有不同的方向选择；

    注：当屏幕发生旋转的时候,activity会重走生命周期,但是如果不希望重走生命周期,那么可以设置android:configChanges=”orientation|screenSize|keyboardHidden”,这样当屏幕发生旋转的时候便是回调onConfigurationChanged()函数。

源码：
    @IntDef({
            SCREEN_ORIENTATION_UNSET,
            SCREEN_ORIENTATION_UNSPECIFIED,
            SCREEN_ORIENTATION_LANDSCAPE,
            SCREEN_ORIENTATION_PORTRAIT,
            SCREEN_ORIENTATION_USER,
            SCREEN_ORIENTATION_BEHIND,
            SCREEN_ORIENTATION_SENSOR,
            SCREEN_ORIENTATION_NOSENSOR,
            SCREEN_ORIENTATION_SENSOR_LANDSCAPE,    //6
            SCREEN_ORIENTATION_SENSOR_PORTRAIT,
            SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
            SCREEN_ORIENTATION_REVERSE_PORTRAIT,
            SCREEN_ORIENTATION_FULL_SENSOR,
            SCREEN_ORIENTATION_USER_LANDSCAPE,
            SCREEN_ORIENTATION_USER_PORTRAIT,
            SCREEN_ORIENTATION_FULL_USER,
            SCREEN_ORIENTATION_LOCKED
    })
    */
    static int getScreenOrientation();
    static void setScreenOrientation(int orient);

    //设置和取消屏幕常亮
    static void keepScreenWake(bool bOn);

    //得到SD卡路径(内置存储)
    static QString getSdcardPath();
    static QString getExternalStorageDirectory();

    //不能用!!!
    static QString getNetworkState();

    static QString getAndroidInfo(int type);

    static bool checkPermission(const QString& strPermission);
    //请求权限，timeoutMS为超时毫秒（用户没选，超时后会继续运行代码，但返回false）
    static bool requestPermission(const QString& strPermission, int timeoutMs = INT_MAX);

    static void showToast(const QString &msg);
    static void showToast1(const QString &msg);

    //安装APK
    static void installApk(const QString &filePath);

    //自定义 控制台输出
    static void customAndroidMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);


    //alipay
    static void setAlipayInfo(QString appId,
                              QString pId,
                              QString targetId,
                              QString rsa2Private,
                              QString rsaPrivate);
    static void aliPayVersion();
    static void aliPay(float total_amount, int timeout_express, QString body);
};


#elif defined(Q_OS_MACOS)

#define FIXLOCALPATH_R(x) (QCoreApplication::applicationDirPath() + "/" + x)            //只读本地文件路径
#define FIXLOCALPATH_W(x) (QCoreApplication::applicationDirPath() + "/" + x)            //读写本地文件路径

#define FIXRESOURCEPATH_R(x) (QString(":/") + x)     //只读资源路径转换
#define FIXRESOURCEURL_R(x) (QString("qrc:/") + x)   //只读资源URL转换


class _Platform: public QObject
{
    Q_OBJECT
    Q_ENUMS(QStandardPaths::StandardLocation)
public:
    explicit _Platform(QObject *parent = nullptr): QObject(parent){}
    virtual ~_Platform(){}
public slots:
    PLATFORM_GLOBAL_FUNCTION


};



#elif defined(Q_OS_IOS)

#define FIXLOCALPATH_R(x) (QCoreApplication::applicationDirPath() + "/" + x)            //只读本地文件路径
#define FIXLOCALPATH_W(x) (QCoreApplication::applicationDirPath() + "/" + x)

#define FIXRESOURCEPATH_R(x) (QString(":/") + x)     //只读资源路径转换
#define FIXRESOURCEURL_R(x) (QString("qrc:/") + x)   //只读资源URL转换


class _Platform: public QObject
{
    Q_OBJECT
    Q_ENUMS(QStandardPaths::StandardLocation)
public:
    explicit _Platform(QObject *parent = nullptr): QObject(parent){}
    virtual ~_Platform(){}
public slots:
    PLATFORM_GLOBAL_FUNCTION


};



#elif defined(Q_OS_LINUX)   //linux,必须在Q_OS_ANDROID之后,因为Android环境会即将Linux也定义

#define FIXLOCALPATH_R(x) x            //只读本地文件路径
#define FIXLOCALPATH_W(x) x            //读写本地文件路径

#define FIXRESOURCEPATH_R(x) (QString(":/") + x)     //只读资源路径转换
#define FIXRESOURCEURL_R(x) (QString("qrc:/") + x)   //只读资源URL转换


class _Platform: public QObject
{
    Q_OBJECT
    Q_ENUMS(QStandardPaths::StandardLocation)
public:
    explicit _Platform(QObject *parent = nullptr): QObject(parent){}
    virtual ~_Platform(){}
public slots:
    PLATFORM_GLOBAL_FUNCTION


    bool checkOnly();
};



#else

#define FIXLOCALPATH_R(x) x            //只读本地文件路径
#define FIXLOCALPATH_W(x) x            //读写本地文件路径

#define FIXRESOURCEPATH_R(x) (QString(":/") + x)     //只读资源路径转换
#define FIXRESOURCEURL_R(x) (QString("qrc:/") + x)   //只读资源URL转换


class _Platform: public QObject
{
    Q_OBJECT
    Q_ENUMS(QStandardPaths::StandardLocation)
public:
    explicit _Platform(QObject *parent = nullptr): QObject(parent){}
    virtual ~_Platform(){}
public slots:
    PLATFORM_GLOBAL_FUNCTION


};



#endif


#endif // PLATFORM_H
